package org.erp.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.erp.common.page.PageQueryModel;
import org.erp.product.domain.dto.DickerDto;
import org.erp.product.domain.dto.RepairInfoQueryDto;
import org.erp.product.domain.dto.TransferLogAddDto;
import org.erp.product.domain.entity.RepairInfo;
import org.erp.product.domain.vo.ProductInfoVo;
import org.erp.product.domain.vo.RepairInfoVo;
import org.erp.product.infrastructure.config.RepairStateFlow;
import org.erp.product.infrastructure.convert.RepairInfoConvert;
import org.erp.product.infrastructure.enums.RepairEventEnum;
import org.erp.product.infrastructure.enums.RepairStatusEnum;
import org.erp.product.infrastructure.exception.ProductException;
import org.erp.product.infrastructure.mapper.RepairInfoMapper;
import org.erp.product.service.RepairInfoService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Log4j2
@Service
@AllArgsConstructor
public class RepairInfoServiceImpl extends ServiceImpl<RepairInfoMapper, RepairInfo> implements RepairInfoService {

    private final RepairInfoConvert repairInfoConvert;

    @Override
    public List<RepairInfo> searchAndVerify(List<DickerDto> dickerDtoList, RepairEventEnum repairEventEnum) {
        Set<Long> stockIds = dickerDtoList.stream().map(DickerDto::getStockId).collect(Collectors.toSet());
        List<RepairInfo> list = this.list(new QueryWrapper<RepairInfo>().lambda()
                .in(RepairInfo::getStockId, stockIds));
        for (RepairInfo repairInfo : list) {
            try {
                RepairStateFlow.next(RepairStatusEnum.getByCode(repairInfo.getRepairStatus()), repairEventEnum);
            } catch (Exception e) {
                throw new ProductException("维修操作事件id为: " + repairInfo.getId() + " 状态不允许执行该操作");
            }
        }
        return list;
    }

    @Override
    public TransferLogAddDto updateBatchStatus(List<RepairInfo> repairInfoList, RepairEventEnum repairEventEnum) {
        Integer oldStatus = repairInfoList.get(0).getRepairStatus();
        repairInfoList.forEach(w -> {
            RepairStatusEnum nextStatus = RepairStateFlow.next(RepairStatusEnum.getByCode(w.getRepairStatus()), repairEventEnum);
            w.setRepairStatus(nextStatus.getCode());
        });
        this.baseMapper.updateBatchById(repairInfoList);
        TransferLogAddDto transferLogAddDto = new TransferLogAddDto();
        transferLogAddDto.setOldStatus(oldStatus);
        transferLogAddDto.setRepairInfoList(repairInfoList);
        return transferLogAddDto;
    }

    @Override
    public PageQueryModel<RepairInfoVo> pageList(RepairInfoQueryDto repairInfoQueryDto) {
        Page<RepairInfo> page = this.page(repairInfoQueryDto.buildPage(), new QueryWrapper<RepairInfo>().lambda()
                .eq(StringUtils.isNotBlank(repairInfoQueryDto.getProductCode()), RepairInfo::getProductCode, repairInfoQueryDto.getProductCode())
                .eq(null != repairInfoQueryDto.getRepairStatus(), RepairInfo::getRepairStatus, repairInfoQueryDto.getRepairStatus())
                .ge(null != repairInfoQueryDto.getStartTime(), RepairInfo::getCreateTime, repairInfoQueryDto.getStartTime())
                .le(null != repairInfoQueryDto.getEndTime(), RepairInfo::getCreateTime, repairInfoQueryDto.getEndTime()));

        return PageQueryModel.of(page.getPages(),page.getRecords().stream().map(repairInfoConvert::convertVo).toList());
    }
}
